﻿using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Modules.CheckIn.Entitys;
using Modules.CheckIn.Repositories;
using Modules.Person;
using MySql.Data.MySqlClient;
using PetaPoco;
using Pipelines.Sockets.Unofficial.Arenas;
using PmSoft;
using PmSoft.Caching.Redis;
using PmSoft.DBContext;

namespace Modules.CheckIn
{
    [UseDI(ServiceLifetime.Scoped)]
    public class CheckInDetailService
    {
        private readonly CheckInDetailRepository checkInDetailRepository;
        private readonly CheckinDbContext dbContext;
        private readonly PersonService personService;
        private readonly IConfiguration configuration;
        private readonly PmSoftRedisCache redisCache;

        /// <summary>
        /// 考勤统计起始时间
        /// </summary>
        private DateTime checkInStartTime = DateTime.Now.AddMonths(-1);

        public CheckInDetailService(CheckInDetailRepository checkInDetailRepository, CheckinDbContext dbContext, IConfiguration configuration, PersonService personService, PmSoftRedisCache redisCache)
        {
            this.checkInDetailRepository = checkInDetailRepository;
            this.dbContext = dbContext;
            this.personService = personService;
            this.configuration = configuration;
            this.redisCache = redisCache;
            checkInStartTime = this.configuration.GetValue<DateTime>("CheckinStartTime");
        }

        public CheckInDetail? GetCheckInDetail(string id, int month)
        {
            return checkInDetailRepository.GetCheckInDetail(id, month);
        }

        /// <summary>
        /// 人员统计按月
        /// </summary>
        /// <param name="query"></param>
        /// <param name="pageNum"></param>
        /// <param name="pageSize"></param>
        /// <returns></returns>
        public IPagedList<CheckInDetail> GetCheckInDetailsByPersonGroup(CheckInDetailMonthQuery query, int pageNum, int pageSize)
        {
            if (!string.IsNullOrEmpty(query.Keywords))
            {
                query.personIds = personService.GetPersonsByNames(query.Keywords).Select(a => a.PersonId).ToList();
            }
            return checkInDetailRepository.GetCheckInDetailsByPersonGroup(query, pageNum, pageSize);
        }

        /// <summary>
        /// 人员考勤明细，按月份筛选
        /// </summary>
        /// <param name="query"></param>
        /// <param name="pageNum"></param>
        /// <param name="pageSize"></param>
        /// <returns></returns>
        public IPagedList<CheckInDetail> GetCheckInDetailsByMonth(CheckInDetailMonthQuery query, int pageNum, int pageSize)
        {
            if (!string.IsNullOrEmpty(query.Keywords))
            {
                query.personIds = personService.GetPersonsByNames(query.Keywords).Select(a => a.PersonId).ToList();
            }
            return checkInDetailRepository.GetCheckInDetailsByMonth(query, pageNum, pageSize);
        }

        public IPagedList<CheckInDetail> GetCheckInDetailMonths(CheckInDetailQuery query, int pageNum, int pageSize)
        {
            if (query.StartDate.HasValue && query.StartDate < checkInStartTime)
                query.StartDate = checkInStartTime;
            if (query.EndDate.HasValue && query.EndDate > DateTime.Now.Date)
                query.EndDate = DateTime.Now.Date;
            if (query.StartDate > query.EndDate)
                query.StartDate = query.EndDate;
            if (!string.IsNullOrEmpty(query.Keywords))
            {
                query.personIds = personService.GetPersonsByNames(query.Keywords).Select(a => a.PersonId).ToList();
            }
            return checkInDetailRepository.GetCheckInDetailMonths(query, pageNum, pageSize);
        }

        public void Create(CheckInDetail entity)
        {
            string tableName = "checkin_detail_" + DateTime.Now.ToString("yyyyMM");
            Sql sql = Sql.Builder.Append($"INSERT INTO {tableName} (project_id,member_id,entry_exit_mark,person_id,group_id,data_sources,status,checkin_date,create_time) VALUES(@0, @1, @2, @3, @4, @5, @6, @7, @8)",
                entity.ProjectId,
                entity.MemberId,
                entity.EntryExitMark,
                entity.PersonId,
                entity.GroupId,
                entity.DataSources,
                entity.Status,
                entity.CheckinDate,
                entity.CreateTime
                );
            try
            {
                dbContext.Execute(sql);
            }
            catch (MySqlException e)
            {
                if (e.Number == 1146)
                {
                    try
                    {
                        string sqlCreateTable = $"CREATE TABLE {tableName} LIKE checkin_detail";
                        dbContext.Execute(sqlCreateTable);
                    }
                    finally { }
                    dbContext.Execute(sql);
                }
                else
                    throw e;
            }
        }

        public void CreateTable(string tableName)
        {
            string sqlCreateTable = $"CREATE TABLE {tableName} LIKE checkin_detail";
            dbContext.Execute(sqlCreateTable);
        }

        public IEnumerable<int> GetCheckInDetailPersonForm(int memberId, int month)
        {
            return checkInDetailRepository.GetCheckInDetailPersonMonthForm(memberId, month);
        }

        /// <summary>
        /// 查询项目出勤人数
        /// </summary>
        /// <param name="query"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public int GetCheckInDetailCount(ProjectCheckinCountQuery query)
        {
            return checkInDetailRepository.GetCheckInDetailCount(query);
        }

        /// <summary>
        /// 查询考勤人员数量
        /// </summary>
        /// <param name="query"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public IEnumerable<PersonCount> GetPersonCountsByProjectId(ProjectCheckinCountQuery query)
        {
            return checkInDetailRepository.GetPersonCountsByProjectId(query);
        }

        public IEnumerable<PersonCount> GetPersonCountsByProjectIdGroupPersonAndGroupId(ProjectCheckinCountQuery query)
        {
            return checkInDetailRepository.GetPersonCountsByProjectIdGroupPersonAndGroupId(query);
        }

        //public IEnumerable<CheckInDetail> GetCheckInDetailsByProjectIdAndMonth(int projectId, int month)
        //{
        //    return checkInDetailRepository.GetCheckInDetailsByProjectIdAndMonth(projectId, month);
        //}

        /// <summary>
        /// 获取班组成员指定日期的考勤明细
        /// </summary>
        /// <param name="checkinDate"></param>
        /// <param name="memberId"></param>
        /// <returns></returns>
        public IEnumerable<CheckInDetail> GetCheckInDetailsByMonthAndCheckDateAndMemberId(DateTime checkinDate, int memberId)
        {
            return checkInDetailRepository.GetCheckInDetailsByMonthAndCheckDateAndMemberId(checkinDate, memberId);
        }

        public IEnumerable<CheckInDetail> GetCheckinDetailsByMonthAndMemberId(int month, int memberId)
        {
            return checkInDetailRepository.GetCheckinDetailsByMonthAndMemberId(month, memberId);
        }

        public IEnumerable<CheckInDetail> GetCheckinDetailsByMonthAndMemberIds(int month, IEnumerable<int> memberIds)
        {
            return checkInDetailRepository.GetCheckinDetailsByMonthAndMemberIds(month, memberIds);
        }
    }
}